home *** CD-ROM | disk | FTP | other *** search
- #include <fstream.h>
- #include <malloc.h>
- #include <string.h>
- #include "pcx2cel.h"
-
- #define BSIZE 16384
- #define HIMASK 0xF0
- #define LOMASK 0xF
-
- byte Palblock[768];
- pcxHeader PcxH;
-
-
- void headerInit() {
- PcxH.maker=0xA;
- PcxH.version=5;
- PcxH.code=1;
- PcxH.bpp=8;
- PcxH.x1=0; PcxH.y1=0;
- PcxH.hres=0x96;
- PcxH.vres=0x96;
- for (int i=0; i<48; i++)
- PcxH.tripletData[i]=Palblock[i+1]; //16 col palette area.
- PcxH.vmode=0;
- PcxH.numPlanes=1;
- PcxH.paletteFlag=1;
- for (i=0; i<58; i++)
- PcxH.unusedData[i]=0;
- }
-
-
- int readKCF(char *in) {
-
- byte *paltemp=new byte[320];
- byte *poshold=paltemp;
- byte *Pblockpos=Palblock;
-
- ifstream myInStream(in, ios::binary);
- if (!myInStream) {
- cerr << in << ": Cannot open input file\n";
- delete paltemp;
- return 1;
- }
- *Pblockpos++=12; //Initial 12 value sep pic from palette.
- myInStream.read(paltemp, 320);
- for (int i=0; i<160; i++) {
- *Pblockpos++=(HIMASK & *poshold); //mult by 16 upper nibble; R
- *Pblockpos++=(LOMASK & *(poshold+1)) <<4; //mult by 16 lower nibble; G
- *Pblockpos++=(LOMASK & *poshold) <<4; // B value
- poshold+=2; }
-
- for (i=0; i<288; i++)
- *Pblockpos++=0; //zero out remaining entries
- myInStream.close();
- //At this point, block filled with palvals. Others written will be 0.
-
- return 0;
- }
-
- void RLEblock(int &val, int &lastval, long &writecount, int &count, byte *&outpos) {
- if (val==lastval) {
- count++;
- if (count==63){
- *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2; count=0;}
- } else { //this case, new val trigger.
- if (count) {
- if (count >1) {
- *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
- } else {
- *outpos++=lastval; writecount++; }
- lastval=val;
- count=1;
- }//if (count)
- } //else
- }
-
- int convertCELPic(char *in, char *out) {
- byte *inbuffer=new byte[BSIZE];
- byte *outbuffer=new byte[BSIZE*2];
- byte buf[128];
- byte *inbuf=buf;
- struct sizedat{
- int width, height;
- } sizedata;
- sizedat *sizeptr=&sizedata;
-
- ifstream myInStream(in, ios::binary);
- if (!myInStream) {
- cerr << in << ": Cannot open input file\n";
- delete inbuffer;
- delete outbuffer;
- return 1;}
- ofstream myOutStream(out, ios::binary);
- if (!myOutStream) {
- cerr << out << ": not able to write file.\n";
- delete inbuffer;
- delete outbuffer;
- return 1;}
- myInStream.read(inbuf, 4);
- memcpy(sizeptr, inbuf, 4);
- PcxH.x2=sizeptr->width-1;
- PcxH.y2=sizeptr->height-1;
- PcxH.bpl=sizeptr->width + sizeptr->width % 2;
-
- //write header block; the breakdown from weirdness.
- myOutStream.write((byte *)&PcxH, 128);
-
- //write always <=input block. Keep track of all to write, as well as counter.
- //remember that double size of write block due to decompression from nibble
-
- int count=0, val;
- long writecount=0, totalread=0;
- int linesize=PcxH.bpl>>1;
- long readmax;
- long readlimit=(BSIZE/linesize)*linesize; //round # of lines.
- byte *inpos=inbuffer;
- byte *outpos=outbuffer;
- int lastval=0;
- myInStream.seekg(0, ios::end);
- long size = myInStream.tellg();
- myInStream.seekg(4, ios::beg);
-
-
- while (totalread < size) {
- if (size-totalread>BSIZE) readmax=readlimit; else readmax=size-totalread;
- myInStream.read(inbuffer, readmax);
- totalread+=readmax;
- for (int i=0; i<readmax; i+=linesize) {
- lastval=(HIMASK & *inpos) >>4; //new line, fresh start
- for (int j=1; j<=linesize; j++) {
- val=(HIMASK & *inpos) >>4;
- RLEblock(val, lastval, writecount, count, outpos);
- if (count==0) lastval=(LOMASK & *inpos); //last=next.
- val=(LOMASK & *inpos);
- RLEblock(val, lastval, writecount, count, outpos);
- if (count==0) lastval=(HIMASK & *(++inpos)) >>4; else *inpos++;
- } //line decode loop
-
- //if remaining vals unwritten, write here. finish off.
- if (count) {
- if (count >1) {
- *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
- } else {
- *outpos++=lastval; writecount++; }
- count=0;
- }//if (count)
-
- } //buffer decode loop
-
-
- myOutStream.write(outbuffer, writecount);
- writecount=0;
- inpos=inbuffer; outpos=outbuffer;
- } //while loop
-
- myOutStream.write(Palblock, 769);
- delete inbuffer; delete outbuffer;
- myInStream.close();
- myOutStream.close();
- return 0;
- }
-
- int main(int argc, char *argv[]) {
- char *KCFFile;
- char *filein;
- char fileout[15];
- char *temp;
-
- if (argc<3) {
- cerr << "Must be in format: cel2pcx <.kcf file> <.cel to convert> ...\n";
- cerr << "The .kcf and .cel suffixes must be included.\n";
- return 0; }
- KCFFile=argv[1];
- if (readKCF(KCFFile)) return 0;
- headerInit(); //inits headerblock;
- for (int i=2; i<argc; i++) { //remaining args for file names
- filein=argv[i];
- temp=filein;
- for (int j=0; *temp!='.'; j++, temp++)
- fileout[j]=*temp;
- fileout[j]='\0';
- strcat(fileout, ".pcx\0");
- if (!convertCELPic(filein, fileout))
- cerr << filein << " converted \n";
- else
- cerr << filein << " not converted.\n";
- }
- cerr << "Done.\n";
- return 0;
- }